<template>
  <div v-loading="loading">
    <div v-for="data in searchUsers" :key="data.key" class="search-user-item">
      <div class="inner-user">
        <VxeCheckbox
          :model-value="isChecked(data)"
          :disabled="data.disabled"
          @change="handleRowCheck(data)"
        >
          <span :class="{ activeColor: data.isChecked }">
            <el-icon><Person /></el-icon>
            <hight-light
              style="margin-left: 4px"
              :text="data.name"
              :reg-text="searchKey"
            />
          </span>
        </VxeCheckbox>
      </div>
      <div v-for="des in data.deptInfo" :key="des.id" class="dept-info">
        {{ fmtDept(des) }}
      </div>
    </div>
    <vxe-table
      v-if="searchResults.length > 0 || !searchUsers.length"
      ref="searchTable"
      :data="searchResults"
      :loading="loading"
      border="none"
      :row-config="{ isCurrent: false, isHover: true, keyField: 'key' }"
      :show-header="false"
      :tree-config="{
        transform: false,
        parentField: 'parentId',
        iconOpen: 'vxe-icon-square-minus',
        iconClose: 'vxe-icon-square-plus'
      }"
    >
      <vxe-column field="key" tree-node>
        <template #default="{ row }">
          <div class="custom-checkbox">
            <template v-if="row.type == type">
              <VxeCheckbox
                :model-value="isChecked(row)"
                :disabled="row.disabled"
                @change="handleRowCheck(row)"
              >
                <span :class="{ activeColor: row.isChecked }">
                  <el-icon v-if="row.type == 2"><Person /></el-icon>
                  <hight-light
                    style="margin-left: 4px"
                    :text="row.name"
                    :reg-text="searchKey"
                  />
                </span>
              </VxeCheckbox>
            </template>
            <template v-else>
              <svg-icon name="department"></svg-icon>
              <hight-light
                style="margin-left: 4px"
                :text="row.name"
                :reg-text="searchKey"
              />
            </template>
          </div>
        </template>
      </vxe-column>
    </vxe-table>
  </div>
</template>

<script setup lang="ts">
  import { computed, ref } from 'vue';
  import type { SSModelValue, TData } from '../props';
  import { Person } from '@vicons/ionicons5';
  import XEUtils from 'xe-utils';
  import hightLight from './hightLight.vue';
  import { flatTreeData, genUserDeptsData } from '../utils';

  const emit = defineEmits<{
    (event: 'update:modelValue', value: SSModelValue): void;
    (event: 'change'): void;
  }>();

  const props = withDefaults(
    defineProps<{
      modelValue: SSModelValue;
      multiple?: boolean;
      type?: 1 | 2;
      options: Array<any>;
    }>(),
    {
      multiple: false,
      parentField: 'parentId',
      type: 1
    }
  );

  const loading = ref<boolean>(false);

  const searchKey = ref('');

  const valueBak = computed({
    get() {
      return props.modelValue;
    },
    set(val: SSModelValue) {
      emit('update:modelValue', val);
      emit('change');
    }
  });

  const flatOptions = computed(() => {
    if (props.options == undefined) return [];
    if (props.type === 1) return flatTreeData(props.options);
    return genUserDeptsData(props.options);
  });

  const searchResults = ref<any>([]);

  const searchUsers = ref<TData[]>([]);

  const isChecked = (row: any) => {
    if (!valueBak.value) return false;
    if (props.multiple) {
      return !!valueBak.value?.find((item: TData) => {
        return item.id == row.id && item.type == row.type;
      });
    } else {
      return (
        (valueBak.value as TData).id == row.id &&
        (valueBak.value as TData).type == row.type
      );
    }
  };

  const handleDiyCheckbox = (row: any) => {
    if (row.disabled) return;
    if (!valueBak.value) {
      const selected = flatOptions.value?.find((item) => item.id == row.id);
      if (!selected) return;
      valueBak.value = [selected];
    } else {
      const index = valueBak.value.findIndex((item: any) => item.id === row.id);
      if (index > -1) {
        valueBak.value.splice(index, 1);
      } else {
        valueBak.value.push(
          flatOptions.value?.find((item) => item.id === row.id)
        );
      }
    }
  };

  const handleDiyRadio = (row: any) => {
    if (row.disabled) return;
    const selected = flatOptions.value?.find((item) => item.id == row.id);
    valueBak.value = selected;
  };

  const handleRowCheck = (row: any) => {
    if (row.disabled) return;
    return props.multiple ? handleDiyCheckbox(row) : handleDiyRadio(row);
  };

  const fmtDept = (depts: []) => {
    return depts.map((item: any) => item.name).join('/');
  };

  defineExpose({
    clear() {
      searchKey.value = '';
    },
    search(val?: string) {
      searchKey.value = val || '';
      const filterName = XEUtils.toValueString(val).trim().toLowerCase();
      const treeData = [...flatOptions.value];
      const depts = [];
      const users: any[] = [];
      while (treeData.length) {
        const el = treeData.shift();
        if (el && el.name.toLowerCase().indexOf(filterName) > -1) {
          if (el.type == 2) {
            const hadIdx = users.find((item) => item.id === el.id);
            if (!hadIdx) users.push(el);
          } else {
            depts.push(el);
          }
        }
      }
      searchResults.value = depts;
      searchUsers.value = users;
    }
  });
</script>

<style scoped>
  @import './index.less';
</style>
